/*
 * 本代码适用于ESP8266 NodeMCU + 12864显示屏
 * 7pin SPI引脚，正面看，从左到右依次为GND、VCC、D0、D1、RES、DC、CS
 *    ESP8266 ---  OLED
 *      3V    ---  VCC
 *      G     ---  GND
 *      D7    ---  D1
 *      D5    ---  D0
 *      D2orD8---  CS
 *      D1    ---  DC
 *      RST   ---  RES
 * 4pin IIC引脚，正面看，从左到右依次为GND、VCC、SCL、SDA
 *      ESP8266  ---  OLED
 *      3.3V     ---  VCC
 *      G (GND)  ---  GND
 *      D1(GPIO5)---  SCL
 *      D2(GPIO4)---  SDA
 */

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <U8g2lib.h>

//---------------修改此处""内的信息-----------------------
const char *ssid = "www.zhenxin.xyz";     //WiFi SSID
const char *password = "Your Password";  //WiFi密码
String biliuid = "7430720";         //bilibili UID
//-------------------------------------------------------

//若屏幕使用SH1106，只需把SSD1306改为SH1106即可
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/4, /* dc=*/5, /* reset=*/3);
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 5); //D-duino

const unsigned long HTTP_TIMEOUT = 5000;
WiFiClient client;
HTTPClient http;
String response;
int follower = 0;
const int slaveSelect = 5;
const int scanLimit = 7;

void setup()
{
    Serial.begin(9600);
    while (!Serial)
        continue;
    Serial.println("ESP8266 BiliBili Fans, version v1.0");
    initdisplay();
    Serial.println("OLED Ready");
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(0, 14);
    u8g2.print("BiliBili Fans"); 
    u8g2.setCursor(0, 30);
    u8g2.print("Version 1.0");
    u8g2.setCursor(0, 44);
    u8g2.print("Connecting WiFi");
    u8g2.setCursor(0, 61);
    u8g2.print("BiliBili: QG真心");
    u8g2.sendBuffer();
    Serial.print("Connecting WiFi...");
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED){
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(0, 14);
    u8g2.print("BiliBili Fans");
    u8g2.setCursor(0, 30);
    u8g2.print("WiFi Connected");
    u8g2.setCursor(0, 44);
    u8g2.print(WiFi.localIP());
    u8g2.setCursor(0, 61);
    u8g2.print("BiliBili: QG真心");
    u8g2.sendBuffer();
    delay(2000);
}

void initdisplay()
{
  u8g2.begin();
  u8g2.enableUTF8Print();
}

bool getJson()
{
    bool r = false;
    http.setTimeout(HTTP_TIMEOUT);
    http.begin("http://api.bilibili.com/x/relation/stat?vmid=" + biliuid);
    int httpCode = http.GET();
    if (httpCode > 0){
        if (httpCode == HTTP_CODE_OK){
            response = http.getString();
            //Serial.println(response);
            r = true;
        }
    }else{
        Serial.printf("[HTTP] GET JSON failed, error: %s\n", http.errorToString(httpCode).c_str());
        printError("HTTP","Get Failed","Check UID");
        r = false;
    }
    http.end();
    return r;
}

bool parseJson(String json)
{
    const size_t capacity = JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 70;
    DynamicJsonDocument doc(capacity);
    deserializeJson(doc, json);

    int code = doc["code"];
    const char *message = doc["message"];

    if (code != 0){
        Serial.print("[API]Code:");
        Serial.print(code);
        Serial.print(" Message:");
        Serial.println(message);
        return false;
    }

    JsonObject data = doc["data"];
    unsigned long data_mid = data["mid"];
    int data_follower = data["follower"];
    if (data_mid == 0){
        Serial.println("[JSON] FORMAT ERROR");
        printError("JSON","Format Error","Check Network");
        return false;
    }
    Serial.print("UID: ");
    Serial.print(data_mid);
    Serial.print(" follower: ");
    Serial.println(data_follower);

    follower = data_follower;
    return true;
}

void displayNum()
{
    int i = random(0, 2);
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(i, 14);
    u8g2.print("UID: " + biliuid);
    u8g2.setFont(u8g2_font_logisoso24_tr);
    u8g2.setCursor(i, 44);
    u8g2.print(follower);
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(i, 61);
    u8g2.print("BiliBili: QG真心");
    u8g2.sendBuffer();
}

void loop()
{
    if (WiFi.status() == WL_CONNECTED){
        if (getJson()){
            if (parseJson(response)){
                displayNum();
            }
        }
    }else{
        Serial.println("[WiFi] Waiting to reconnect...");
        printError("WiFi","WiFi reconnect","Please Waiting");
    }
    delay(1000);
}

void printError(String errorType,String errorString,String errorString2)
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.setCursor(0, 14);
    u8g2.print("Error: " + errorType);
    u8g2.setCursor(0, 30);
    u8g2.print(errorString);
    u8g2.setCursor(0, 44);
    u8g2.print(errorString2);
    u8g2.setCursor(0, 61);
    u8g2.print("BiliBili: QG真心");
    u8g2.sendBuffer();
}
